package com.fastjars.business.spring.resolver.tree;

import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * TreeService
 * 树形结构
 * @author Brant Liu <br> 邮箱：<br>lbf1988@qq.com <br>日期：<br>2017/12/24
 * @version 1.0.0
 */
public class TreeService<T extends BaseTree<T,ID> , ID extends Serializable> implements TreeInterface<T, ID> {

    public void recursionFill(List<T> sourceList,List<T> targetList,T t){
        recursionFill(sourceList, targetList,null, t);
    }

    public void recursionFill(List<T> sourceList,List<T> targetList,List<ID> checkedList ,T t){
        List<T> list = getChildList(sourceList, t);
        for(T nextPojo : list){
            targetList.add(nextPojo);
            if(hasChild(sourceList,nextPojo)){
                nextPojo.setHasChild(true);
                recursionFill(sourceList,targetList,checkedList,nextPojo);
            }
        }
    }

    public void recursionFillChildren(List<T> sourceList,List<T> targetList,T t){
        recursionFillChildren(sourceList, targetList,null, t);
    }

    public void recursionFillChildren(List<T> sourceList,List<T> targetList,List<ID> checkedList,T t){
        List<T> list = getChildList(sourceList, t);
        for(T nextPojo : list){
            List<T> childrenList = new ArrayList<>();
            if(!CollectionUtils.isEmpty(checkedList) && checkedList.contains(nextPojo.getId())){
                nextPojo.setChecked(true);
            }
            if(hasChild(sourceList,nextPojo)){
                nextPojo.setHasChild(true);
                recursionFillChildren(sourceList,childrenList,checkedList,nextPojo);
            }
            if(!CollectionUtils.isEmpty(checkedList) && checkedList.contains(nextPojo.getId()) && !CollectionUtils.isEmpty(childrenList)){
                nextPojo.setSpread(true);
            }
            if(!CollectionUtils.isEmpty(childrenList)){
                nextPojo.setChildren(childrenList);
            }
            targetList.add(nextPojo);
        }
    }

    @Override
    public List<T> getChildTreeObjects(List<T> list, ID parentId) {
        List<T> returnList = new ArrayList<T>();
        for (Iterator<T> iterator = list.iterator(); iterator.hasNext();) {
            T res= (T) iterator.next();
            /**
             * 判断第一个对象是否为第一个节点
             */
            if(null == parentId) {
                if (res.getParentId() == parentId) {
                    recursionFn(list, res);
                    returnList.add(res);
                }
            }else{
                if(null == res.getParentId()){
                    continue;
                }
                if (res.getParentId().toString().equals(parentId.toString())) {
                    recursionFn(list, res);
                    returnList.add(res);
                }
            }
        }
        return returnList;
    }

    @Override
    public void recursionFn(List<T> list, T t) {
        List<T> childsList=getChildList(list, t);
        /**
         * 设置他的子集对象集
         */
        t.setChildren(childsList);
        /**
         * 迭代--这些子集的对象--时候还有下一级的子级对象
         */
        for (T nextChild : childsList) {
            /**
             * 下一个对象，与所有的资源集进行判断
             */
            if(hasChild(list, nextChild)){
                /**
                 * 有下一个子节点,递归
                 */
                Iterator<T> it = childsList.iterator();
                while (it.hasNext()) {
                    T node = it.next();
                    /**
                     * 所有的对象--跟当前这个childsList 的对象子节点
                     */
                    recursionFn(list, node);
                }
            }
        }
    }

    @Override
    public List<T> getChildList(List<T> list, T t) {
        List<T> childsList=new ArrayList<T>();
        Iterator<T> it=list.iterator();
        while(it.hasNext()){
            T child=it.next();
            /**
             * 判断集合的父ID是否等于上一级的id
             */
            if(null == ((BaseTree<T,ID>)t).getId()){
                if(((BaseTree<T,ID>)child).getParentId() == ((BaseTree<T,ID>)t).getId()){
                    childsList.add(child);
                }
            }else{
                if(null == ((BaseTree<T,ID>)child).getParentId()){
                    continue;
                }
                if(((BaseTree<T,ID>)child).getParentId().toString().equals(((BaseTree<T,ID>)t).getId().toString())){
                    childsList.add(child);
                }
            }
        }
        return childsList;
    }

    @Override
    public boolean hasChild(List<T> list, T t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }
}
